package entity

import (
	"sort"

	"gitee.com/linxing_3/sr-core/domain/model"
	"gitee.com/linxing_3/sr-core/domain/model/vo"
	"gitee.com/linxing_3/sr-core/utils/id"
	"gorm.io/gorm"
)

func NewSysMenu() *SysMenu {
	return &SysMenu{}
}

func NewSysMenuBatch(menuIds ...string) ([]any, error) {
	menus := make([]any, 0, len(menuIds))
	for _, menuId := range menuIds {
		menus = append(menus, &SysMenu{MenuId: menuId})
	}
	return menus, nil
}

type MenuType string

const (
	MenuTypeDir  MenuType = "D" // 目录
	MenuTypeMenu MenuType = "M" // 菜单
	MenuTypeBtn  MenuType = "B" // 按钮
)

type SysMenu struct {
	MenuId         string      `json:"menuId" form:"menuId" gorm:"primaryKey;comment:菜单ID"`             // 菜单ID
	Title          string      `json:"title" form:"title" gorm:"size:128;comment:菜单名称"`                 // 菜单名称
	LngTitle       *vo.JSONMap `json:"lngTitle" form:"lngTitle" gorm:"type:json;comment:多语言菜单名称"`       // 多语言菜单名称
	MenuType       MenuType    `json:"menuType" form:"menuType" gorm:"size:1;comment:菜单类型"`             // 菜单类型
	Icon           string      `json:"icon" form:"icon" gorm:"size:128;comment:菜单图标"`                   // 菜单图标
	Pid            string      `json:"pid" form:"pid" gorm:"comment:上级菜单ID"`                            // 上级菜单ID
	Path           string      `json:"path" form:"path" gorm:"size:128;comment:菜单路径"`                   // 菜单路径
	RouteName      string      `json:"routeName" form:"routeName" gorm:"size:128;comment:路由名称"`         // 路由名称
	RoutePath      string      `json:"routePath" form:"routePath" gorm:"size:128;comment:路由路径"`         // 路由路径[TODO:md5]
	Component      string      `json:"component" form:"component" gorm:"size:128;comment:组件路径"`         // 组件路径
	IsFrame        bool        `json:"isFrame" form:"isFrame" gorm:"size:1;comment:是否外链"`               // 是否外链
	FrameUrl       string      `json:"frameUrl" form:"frameUrl" gorm:"size:512;comment:外链地址"`           // 外链地址
	IsHide         int         `json:"isHide" form:"isHide" gorm:"comment:是否隐藏"`                        // 是否隐藏
	MobileTab      int         `json:"mobileTab" form:"mobileTab" gorm:"comment:是否移动端tab中显示"`           // 是否移动端tab中显示
	MobileTabOrder int         `json:"mobileTabOrder" form:"mobileTabOrder" gorm:"comment:移动端tab中显示顺序"` // 移动端tab中显示顺序
	Redirect       string      `json:"redirect" form:"redirect" gorm:"size:128;comment:重定向地址"`          // 重定向地址

	Children []*SysMenu `json:"children,omitempty" gorm:"-"`                    // 子菜单
	Apis     []*SysApi  `json:"apis,omitempty" gorm:"many2many:sys_menu_apis;"` // 菜单对应的api列表
	model.GAllInject
}

func (SysMenu) TableName() string {
	return "sys_menu"
}
func (s *SysMenu) BeforeCreate(tx *gorm.DB) error {
	if s.MenuId == "" {
		s.MenuId = id.GenIDString()
	}
	return nil
}

func (s *SysMenu) SortChildren() {
	if s.Children == nil || len(s.Children) < 1 {
		return
	}

	sort.Slice(s.Children, func(i, j int) bool {
		return s.Children[i].Order < s.Children[j].Order
	})

	for _, child := range s.Children {
		child.SortChildren()
	}
}

// MakeMenuListRelation 生成菜单列表关系
// :param menus: []*SysMenu 菜单列表
// :return []*SysMenu 跟菜单列表
func MakeMenuListRelation(menus []*SysMenu) (result []*SysMenu) {
	if menus == nil || len(menus) < 1 {
		return
	}

	menuMap := make(map[string]*SysMenu)
	for _, menu := range menus {
		menuMap[menu.MenuId] = menu
	}

	for _, menu := range menus {
		if menuIdNotZero(menu.Pid) {
			parent, ok := menuMap[menu.Pid]
			if ok {
				parent.Children = append(parent.Children, menu)
			}
		} else {
			result = append(result, menu)
		}
	}

	return
}

func menuIdNotZero(menuId string) bool {
	return menuId != "" && menuId != "0"
}
